package com.gitee.wsl.platform

import android.content.pm.ApplicationInfo
import android.content.Context
import android.content.pm.PackageManager
import android.os.Build
import android.util.Log
import java.lang.ref.WeakReference

actual val platform: Platform
    get() = AndroidPlatform


private var _Context: WeakReference<Context>? = null
internal val ContextRef: Context get() {
    return _Context?.get() ?: throw AppDirsException("In android target, please call Application#attachAppDirs() first!")
}

fun Context.attachAppDirs() {
    _Context = WeakReference(this)
}

val Platform.Companion.appContext: Context get() = ContextRef

object AndroidPlatform: Platform{

    override val fileSeparator: String
        get() = ":"

    override val lineSeparator: String
        get() = System.lineSeparator()

    override val current: PlatformType
        get() = platform()

    override fun toString(): String {
        return "Android ${Build.VERSION.SDK_INT}"
    }

    val isRunningInDebugMode =
        // BuildConfig.DEBUG will always be false as for a compiled library its set to false at compile time
        ContextRef.applicationContext?.let {
            it.applicationInfo.flags and ApplicationInfo.FLAG_DEBUGGABLE != 0
        } ?: false

    val appName: String? by lazy {
        try {
            ContextRef.applicationContext?.let { context ->
                context.applicationInfo?.let { applicationInfo ->
                    applicationInfo.loadLabel(context.packageManager).let { label ->
                        "${applicationInfo.packageName ?: applicationInfo.processName}.$label"
                    }
                }
            }
        } catch (e: Throwable) {
            Log.e(null, "Could not get app name;$e" )

            null
        }
    }
}


internal fun platform(): PlatformType {
    return PlatformType.OS.Android(
        arch = arch(),
        buildNumber = Build.VERSION.SDK_INT,
        androidVersion = Build.VERSION.RELEASE,
        isWatch = ContextRef.packageManager.hasSystemFeature(PackageManager.FEATURE_WATCH),
        isTv = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            ContextRef.packageManager.hasSystemFeature(PackageManager.FEATURE_LEANBACK_ONLY)
        } else {
            ContextRef.packageManager.hasSystemFeature(PackageManager.FEATURE_LEANBACK)
        },
    )
}

private fun arch(): Arch {
    Build.SUPPORTED_ABIS.orEmpty().forEach {
        when (it) {
            "arm64-v8a" -> return Arch.Arm64
            "armeabi-v7a" -> return Arch.Arm64
            "x86_64" -> return Arch.X64
            "x86" -> return Arch.X32
        }
    }
    return Arch.UNKNOWN
}

//--> android native
// import kotlinx.cinterop.ByteVar
//import kotlinx.cinterop.ExperimentalForeignApi
//import kotlinx.cinterop.allocArray
//import kotlinx.cinterop.memScoped
//import kotlinx.cinterop.toKString
//import platform.posix.__system_property_get
//import kotlin.experimental.ExperimentalNativeApi
//
//private const val SYSTEM_PROP_BUILD_VERSION: String = "ro.build.version.sdk"
//private const val SYSTEM_PROP_OS_VERSION: String = "ro.build.version.release"
//
//@OptIn(ExperimentalNativeApi::class)
//actual fun platform(): Platform {
//    val nativePlatform = kotlin.native.Platform
//
//    val arch = nativePlatform.cpuArchitecture.asArch()
//
//    val buildSdk = getSystemProp(SYSTEM_PROP_BUILD_VERSION).toInt()
//    val androidVersion = getSystemProp(SYSTEM_PROP_OS_VERSION)
//
//    return Platform.OS.Android(
//        arch = arch,
//        buildNumber = buildSdk,
//        androidVersion = androidVersion,
//        isWatch = false,
//        isTv = false,
//    )
//}
//
//@OptIn(ExperimentalForeignApi::class)
//private fun getSystemProp(prop: String): String = memScoped {
//    val value = allocArray<ByteVar>(1024L)
//    __system_property_get(prop, value)
//    value
//}.toKString()